﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Diagnostics.Eventing.Reader;
using TrayCheckControl.Types;

namespace TrayCheckControl
{
    public class TrayData : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            if(null != PropertyChanged)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        private string id = string.Empty;
        private int countCurrent = 0;
        private int countLimit = 0;
        private Judgement isCountOk = Judgement.None;
        private DateTime pmCurrent = DateTime.MinValue;
        private string pmPeriod = string.Empty;
        private bool isLocked = true;
        private Judgement isPmOk = Judgement.None;
        private Judgement isOk = Judgement.None;
        private string pmCurrentString = string.Empty;
        private string pmValidString = string.Empty;
        private string countAndLimit = string.Empty;
        private System.Drawing.Color resultColor;
        public string Id
        {
            get => this.id;
            set
            {
                this.Init();
                this.id = value;
                this.OnPropertyChanged("Id");
            }
        }
        public int CountCurrent
        {
            get => this.countCurrent;
            set
            {
                this.countCurrent = value;
                this.IsCountOk = this.JudgeCount();
                this.CountAndLimit = $"{this.CountCurrent}/{this.CountLimit}";
                this.OnPropertyChanged("CountCurrent");
            }
        }
        public int CountLimit
        {
            get => this.countLimit;
            set
            {
                this.countLimit = value;
                this.IsCountOk = this.JudgeCount();
                this.CountAndLimit = $"{this.CountCurrent}/{this.CountLimit}";
                this.OnPropertyChanged("CountLimit");
            }
        }
        public Judgement IsCountOk
        {
            get => this.isCountOk;
            private set
            {
                this.isCountOk = value;
                this.OnPropertyChanged("IsCountOk");
            }
        }
        public DateTime PmCurrent
        {
            get => this.pmCurrent;
            set
            {
                this.pmCurrent = value;
                this.IsPmOk = this.JudgePm();
                this.OnPropertyChanged("PmCurrent");
            }
        }
        public string PmPeriod
        {
            get => this.pmPeriod;
            set
            {
                this.pmPeriod = value;
                this.IsPmOk = this.JudgePm();
                this.OnPropertyChanged("PmPeriod");
            }
        }
        public string CountAndLimit
        {
            get => this.countAndLimit;
            private set
            {
                this.countAndLimit = value;
                this.OnPropertyChanged("CountAndLimit");
            }
        }
        public bool IsLocked
        {
            get => this.isLocked;
            set
            {
                this.isLocked = value;
                this.OnPropertyChanged("IsLocked");
            }
        }
        public Judgement IsPmOk
        {
            get => this.isPmOk;
            private set
            {
                this.isPmOk = value;
                this.OnPropertyChanged("IsPmOk");
            }
        }
        public Judgement IsOk
        {
            get => this.isOk;
            private set
            {
                this.isOk = value;
                this.OnPropertyChanged("IsOk");
                switch (this.IsOk)
                {
                    case Judgement.None:
                        this.ResultColor = System.Drawing.Color.Transparent;
                        break;
                    case Judgement.Fail:
                        this.ResultColor = System.Drawing.Color.Red;
                        break;
                    case Judgement.Pass:
                        this.ResultColor = System.Drawing.Color.Green;
                        break;
                    default:
                        this.ResultColor = System.Drawing.Color.Yellow;
                        break;
                }
            }
        }
        public System.Drawing.Color ResultColor
        {
            get => this.resultColor;
            set
            {
                this.resultColor = value;
                this.OnPropertyChanged("ResultColor");
            }
        }
        public string PmCurrentString
        {
            get => this.pmCurrentString;
            private set
            {
                this.pmCurrentString = value;
                this.OnPropertyChanged("PmCurrentString");
            }
        }
        public string PmValidString
        {
            get => this.pmValidString;
            private set
            {
                this.pmValidString = value;
                this.OnPropertyChanged("PmValidString");
            }
        }
        public Judgement JudgeCount()
        {
            this.IsCountOk = this.CountCurrent >= 0 && this.CountCurrent < this.CountLimit ? Judgement.Pass : Judgement.Fail;
            return this.IsCountOk;
        }
        private Judgement JudgePm()
        {
            DateTime endTime;
            switch (this.PmPeriod.ToUpper())
            {
                case "WEEK":
                    endTime = this.PmCurrent.AddDays(7);
                    break;
                case "BI-WEEK":
                    goto case "BIWEEK";
                case "BIWEEK":
                    endTime = this.PmCurrent.AddDays(14);
                    break;
                case "MONTH":
                    endTime = this.PmCurrent.AddMonths(1);
                    break;
                case "BI-MONTH":
                    goto case "BIMONTH";
                case "BIMONTH":
                    endTime = this.PmCurrent.AddMonths(2);
                    break;
                case "SEASON":
                    endTime = this.PmCurrent.AddMonths(4);
                    break;
                case "HALF-YEAR":
                    goto case "HALFYEAR";
                case "HALFYEAR":
                    endTime = this.PmCurrent.AddMonths(6);
                    break;
                case "YEAR":
                    endTime = this.PmCurrent.AddYears(1);
                    break;
                default:
                    endTime = System.DateTime.Now;
                    break;
            }
            this.PmValidString = (endTime - System.DateTime.Now).ToString("c");
            return this.pmCurrent.Date == DateTime.MinValue.Date?
                Judgement.Pass :
                endTime >= System.DateTime.Now ? Judgement.Pass : Judgement.Fail;
        }
        public Judgement Judge()
        {
            this.JudgeCount();
            this.JudgePm();
            this.IsOk = this.IsCountOk == Judgement.Pass && this.IsPmOk == Judgement.Pass /*&& !this.IsLocked*/? Judgement.Pass : Judgement.Fail;
            return this.isOk;
        }
        public void Init()
        {
            this.CountCurrent = -1;
            this.CountLimit = 0;
            this.IsCountOk = Judgement.None;
            this.PmCurrent = DateTime.MinValue;
            this.PmPeriod = string.Empty;
            this.IsPmOk = Judgement.None;
            this.IsOk = Judgement.None;
            this.isLocked = true;
        }
        public void Copy(TrayData trayData)
        {
            this.Id = trayData.id;
            this.CountAndLimit = trayData.countAndLimit;
            this.CountCurrent = trayData.countCurrent;
            this.CountLimit = trayData.countLimit;
            this.IsCountOk = trayData.isCountOk;
            this.PmCurrent = trayData.pmCurrent;
            this.PmPeriod = trayData.pmPeriod;
            this.IsPmOk = trayData.isPmOk;
            this.IsOk = trayData.isOk;
        }
    }
}
